Practicing Kotlin Programming and Android Fundamentals Interview Questions
Course: Android App Development
Topic: Practicing Kotlin Programming and Android Fundamentals Interview Questions
Course Link: Android App Development Course
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to Kotlin Programming and Android Fundamentals Interviews
Kotlin Programming and Android Fundamentals interview preparation helps developers demonstrate their understanding of programming concepts, object-oriented programming, Android application architecture, UI development, lifecycle management, data storage, and application debugging.
Kotlin is a modern, statically typed programming language widely used for Android application development. It supports concise syntax, null safety, object-oriented programming, functional programming, coroutines, and interoperability with Java.
Android fundamentals focus on how applications are structured, how screens are created, how components communicate, how data is stored, and how applications respond to user interactions and system events.
Why Is Interview Practice Important?
- Improves understanding of Kotlin syntax and programming logic.
- Develops problem-solving and debugging skills.
- Strengthens knowledge of Android components and application lifecycle.
- Prepares candidates to explain technical concepts clearly.
- Builds confidence in writing code during technical interviews.
- Helps developers identify knowledge gaps before applying for jobs.
2. Learning Objectives
After completing these notes, learners should be able to:
- Explain fundamental Kotlin programming concepts.
- Understand variables, data types, operators, and control flow.
- Write Kotlin functions and solve basic programming problems.
- Apply object-oriented programming principles.
- Understand null safety, collections, and exception handling.
- Explain Android application components and lifecycle methods.
- Understand Activities, Intents, Fragments, and UI layouts.
- Describe RecyclerView, ViewModel, and basic data persistence.
- Answer common Android technical interview questions.
- Practice coding problems and explain their solutions.
3. Kotlin Programming Fundamentals
3.1 What Is Kotlin?
Kotlin is a statically typed programming language developed by JetBrains. It is widely used for Android development and can run on the Java Virtual Machine (JVM). Kotlin is also used for server-side development, multiplatform applications, and other programming tasks.
Kotlin provides features such as concise syntax, type inference, null safety, extension functions, data classes, higher-order functions, and coroutine support.
3.2 Advantages of Kotlin
- Concise syntax: Reduces repetitive code.
- Null safety: Helps prevent many null-reference errors.
- Java interoperability: Allows Kotlin code to work with Java libraries.
- Data classes: Simplify classes primarily used to hold data.
- Extension functions: Add callable functionality to existing types without modifying their source.
- Coroutines: Support structured asynchronous programming.
- Type inference: Allows the compiler to determine many types automatically.
3.3 Kotlin vs Java
| Feature |
Kotlin |
Java |
| Syntax |
Generally more concise |
Often more verbose |
| Null safety |
Built-in nullable and non-nullable types |
Null references are possible without equivalent built-in type distinctions |
| Data classes |
Supported directly |
Requires conventional classes, records, or other approaches depending on requirements |
| Extension functions |
Supported |
No equivalent language-level extension function feature |
| Coroutines |
Available through Kotlin coroutine libraries |
Uses other concurrency and asynchronous programming approaches |
| Android development |
Widely used and officially supported |
Also supported |
4. Kotlin Variables and Data Types
Variables store values that a program uses during execution. Kotlin provides val and var for declaring variables.
4.1 Immutable Variables Using val
The val keyword declares a read-only reference. After initialization, the reference cannot be reassigned, although the object it refers to may itself be mutable.
fun main() {
val name = "Rahul"
val age = 24
println(name)
println(age)
}
4.2 Mutable Variables Using var
The var keyword declares a variable whose value can be reassigned when its type permits the new value.
fun main() {
var score = 50
score = 85
println(score)
}
4.3 Common Kotlin Data Types
| Type |
Example |
Purpose |
| Int |
val age: Int = 24 |
Whole numbers |
| Long |
val population: Long = 1000000L |
Larger integer values |
| Double |
val price: Double = 99.99 |
Double-precision decimal values |
| Float |
val rating: Float = 4.5f |
Single-precision decimal values |
| Boolean |
val isActive = true |
True or false values |
| Char |
val grade = 'A' |
A single character |
| String |
val city = "Mumbai" |
Text |
Interview Question 1: What Is the Difference Between val and var?
Answer: val declares a read-only reference that cannot be reassigned, while var declares a mutable variable that can be reassigned. Prefer val when reassignment is unnecessary because it makes code easier to reason about.
5. Operators and Control Flow
5.1 Operators in Kotlin
Operators perform calculations, comparisons, logical operations, and assignments.
fun main() {
val a = 10
val b = 3
println(a + b)
println(a - b)
println(a * b)
println(a / b)
println(a % b)
println(a > b)
}
5.2 Conditional Statements
Kotlin supports if, if-else, and when for making decisions.
fun main() {
val marks = 78
if (marks >= 40) {
println("Pass")
} else {
println("Fail")
}
}
5.3 Using when
fun main() {
val day = 3
val dayName = when (day) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6 -> "Saturday"
7 -> "Sunday"
else -> "Invalid day"
}
println(dayName)
}
Interview Question 2: What Is the Difference Between if and when?
Answer: The if expression is commonly used for Boolean conditions and two-way or multi-branch decisions. The when expression is useful when comparing one value against multiple conditions or matching several possible cases.
6. Loops in Kotlin
Loops repeat a block of code until a condition is no longer satisfied or the items in a sequence have been processed.
6.1 For Loop
fun main() {
for (i in 1..5) {
println(i)
}
}
6.2 While Loop
fun main() {
var count = 1
while (count <= 5) {
println(count)
count++
}
}
6.3 Loop Control Statements
break terminates the current loop.
continue skips the current iteration and proceeds to the next one.
Interview Question 3: What Is the Difference Between 1..5 and 1 until 5?
Answer: 1..5 includes both endpoints, producing values from 1 through 5. 1 until 5 excludes the upper endpoint, producing values from 1 through 4.
7. Functions in Kotlin
A function is a reusable block of code that performs a particular task. Functions can accept parameters, return values, and help divide a program into manageable parts.
7.1 Defining a Function
fun add(a: Int, b: Int): Int {
return a + b
}
fun main() {
println(add(10, 20))
}
7.2 Single-Expression Functions
fun square(number: Int): Int = number * number
7.3 Default Arguments and Named Arguments
fun greet(name: String, greeting: String = "Hello") {
println("$greeting, $name!")
}
fun main() {
greet("Asha")
greet(name = "Asha", greeting = "Welcome")
}
Interview Question 4: What Is a Function in Kotlin?
Answer: A function is a named or anonymous block of reusable code. It can accept parameters, perform operations, and return a result. Functions improve readability, modularity, testing, and reuse.
8. Null Safety in Kotlin
Null safety is one of Kotlin's important features. It distinguishes between types that can hold null and types that cannot hold null under normal Kotlin type rules.
8.1 Nullable and Non-Nullable Variables
fun main() {
var name: String = "Amit"
var city: String? = null
name = "Neha"
println(name)
println(city)
}
The question mark in String? means the variable may hold null. A regular String cannot be assigned null in ordinary Kotlin code.
8.2 Safe Call Operator
val name: String? = null
println(name?.length)
The safe call operator ?. accesses a property or calls a function only when the receiver is non-null. Otherwise, the expression evaluates to null.
8.3 Elvis Operator
val name: String? = null
val displayName = name ?: "Guest"
println(displayName)
The Elvis operator ?: supplies a fallback value when the expression on its left is null.
8.4 Not-Null Assertion
val name: String? = "Amit"
println(name!!.length)
The !! operator asserts that a value is non-null. If the value is null, it throws a NullPointerException. Avoid using it unnecessarily, especially when data comes from a database, API, or user input.
Interview Question 5: Why Is Null Safety Important in Kotlin?
Answer: Null safety helps developers identify potentially unsafe null handling at compile time and provides operators for handling nullable values explicitly. It reduces many common null-reference errors but cannot eliminate every possible null-related runtime failure, especially when Java interoperability or unsafe assertions are involved.
9. Object-Oriented Programming in Kotlin
Object-oriented programming (OOP) organizes software around classes and objects. Kotlin supports encapsulation, inheritance, abstraction, and polymorphism.
9.1 Classes and Objects
class Student(
val name: String,
var marks: Int
) {
fun displayDetails() {
println("Name: $name")
println("Marks: $marks")
}
}
fun main() {
val student = Student("Riya", 90)
student.displayDetails()
}
A class defines properties and behavior. An object is an instance of a class.
9.2 Encapsulation
Encapsulation groups data and behavior and controls access to internal state through visibility modifiers and suitable public methods or properties.
class BankAccount {
var balance: Double = 0.0
private set
fun deposit(amount: Double) {
if (amount > 0) {
balance += amount
}
}
}
9.3 Inheritance
Kotlin classes are final by default. A class or member must be declared open when inheritance or overriding is intended.
open class Animal {
open fun sound() {
println("Animal sound")
}
}
class Dog : Animal() {
override fun sound() {
println("Bark")
}
}
9.4 Polymorphism
Polymorphism allows different classes to provide their own implementations of a common method or interface.
open class Shape {
open fun area(): Double = 0.0
}
class Square(private val side: Double) : Shape() {
override fun area(): Double = side * side
}
9.5 Abstraction and Interfaces
interface Printable {
fun printDetails()
}
class Report : Printable {
override fun printDetails() {
println("Printing report")
}
}
Interview Question 6: What Are the Four Pillars of OOP?
Answer:
- Encapsulation: Controls access to data and implementation details.
- Inheritance: Allows a class to derive behavior from another class.
- Polymorphism: Allows common interfaces or parent types to represent different implementations.
- Abstraction: Exposes essential behavior while hiding unnecessary implementation details.
10. Data Classes, Objects, and Companion Objects
10.1 Data Classes
Data classes are useful for representing structured data. Kotlin generates common functions such as equals(), hashCode(), toString(), and copy() based on primary-constructor properties.
data class Employee(
val id: Int,
val name: String
)
fun main() {
val employee = Employee(101, "Priya")
val updatedEmployee = employee.copy(name = "Anaya")
println(employee)
println(updatedEmployee)
}
10.2 Object Declarations
An object declaration creates a singleton object, which can be useful when one shared instance is appropriate.
object AppConfig {
const val APP_NAME = "ChatApp"
}
fun main() {
println(AppConfig.APP_NAME)
}
10.3 Companion Objects
A companion object contains members that can be accessed through the class name. It is commonly used for factory methods and class-level constants.
class User private constructor(val name: String) {
companion object {
fun create(name: String): User {
return User(name)
}
}
}
fun main() {
val user = User.create("Rahul")
println(user.name)
}
Interview Question 7: What Is the Difference Between a Data Class and a Regular Class?
Answer: A data class is designed primarily to hold data and automatically generates several useful methods from its primary-constructor properties. A regular class does not automatically receive the same data-oriented implementations.
11. Collections in Kotlin
Collections store and organize multiple values. Kotlin provides lists, sets, and maps, each with different characteristics.
| Collection |
Description |
Example |
| List |
Ordered collection that can contain duplicate values. |
listOf(10, 20, 20) |
| Set |
Collection of unique elements. |
setOf(10, 20, 30) |
| Map |
Stores key-value pairs. |
mapOf("name" to "Riya") |
| MutableList |
List that supports modification. |
mutableListOf(1, 2, 3) |
Example: Filtering a List
fun main() {
val numbers = listOf(10, 15, 20, 25, 30)
val evenNumbers = numbers.filter {
it % 2 == 0
}
println(evenNumbers)
}
Interview Question 8: What Is the Difference Between List and Set?
Answer: A list maintains an ordered sequence and allows duplicate elements. A set represents unique elements, although ordering behavior depends on the specific set implementation.
12. Lambda Expressions and Higher-Order Functions
A lambda is an anonymous function expression that can be stored in a variable or passed as an argument. A higher-order function accepts a function as a parameter or returns a function.
fun calculate(
a: Int,
b: Int,
operation: (Int, Int) -> Int
): Int {
return operation(a, b)
}
fun main() {
val result = calculate(10, 5) { x, y ->
x + y
}
println(result)
}
Kotlin's collection functions, including map, filter, and forEach, commonly use lambda expressions.
Interview Question 9: What Is a Higher-Order Function?
Answer: A higher-order function accepts another function as a parameter, returns a function, or does both. It enables flexible and reusable behavior without requiring a separate named function for every operation.
13. Exception Handling in Kotlin
Exceptions represent errors or unusual conditions that interrupt normal program execution. Kotlin supports try, catch, and finally for handling exceptions.
fun main() {
try {
val result = 10 / 0
println(result)
} catch (exception: ArithmeticException) {
println("Cannot divide by zero")
} finally {
println("Operation completed")
}
}
The finally block is generally used for cleanup that should occur regardless of whether an exception was thrown. Kotlin does not require checked exceptions to be declared or caught in the same way Java does.
Interview Question 10: What Is the Purpose of try-catch?
Answer: A try-catch block allows a program to handle selected exceptions and respond gracefully instead of allowing the error to terminate the current operation unexpectedly.
14. Coroutines and Asynchronous Programming
Android applications must keep lengthy operations off the main thread to maintain a responsive user interface. Kotlin coroutines provide a structured way to perform asynchronous work, including network requests and database operations.
Important Coroutine Concepts
- suspend function: A function that can suspend its execution without blocking the underlying thread when used in a compatible coroutine context.
- CoroutineScope: Defines the lifecycle and context in which coroutines run.
- Dispatchers.Main: Used for main-thread UI work.
- Dispatchers.IO: Commonly used for blocking I/O operations.
- Dispatchers.Default: Suitable for CPU-intensive work.
- Structured concurrency: Keeps related coroutine work organized within defined scopes.
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
suspend fun loadData(): String {
return withContext(Dispatchers.IO) {
// Perform suitable blocking I/O work here.
"Data loaded"
}
}
This function is illustrative; it must be called from a coroutine or another suspend function. In Android applications, prefer lifecycle-aware scopes such as viewModelScope for work associated with a ViewModel.
Interview Question 11: What Is the Difference Between a Thread and a Coroutine?
Answer: A thread is an operating-system execution resource. A coroutine is a lightweight unit of asynchronous work that can suspend and resume without requiring a dedicated thread for its entire lifetime. Coroutines typically use dispatchers and thread pools to execute work.
15. Android Application Fundamentals
Android applications are built from components that interact with the operating system and with each other. Understanding the purpose of each component is essential for technical interviews.
15.1 Main Android Components
| Component |
Purpose |
| Activity |
Provides an entry point for user interaction and typically hosts a screen. |
| Service |
Supports specific operations that need to run independently of a visible screen, subject to Android execution restrictions. |
| Broadcast Receiver |
Responds to supported broadcast announcements. |
| Content Provider |
Exposes and manages structured data through a defined interface. |
Modern Android applications often use a single-activity architecture with multiple destinations or fragments. Not every application needs to implement all four components directly.
Interview Question 12: What Is an Activity?
Answer: An Activity is an Android application component that represents an entry point for user interaction. It commonly hosts a screen, manages UI-related lifecycle events, and coordinates navigation.
16. Android Activity Lifecycle
The Activity lifecycle describes how an Activity moves through different states as it is created, becomes visible, receives user interaction, loses focus, or is destroyed.
| Callback |
Purpose |
| onCreate() |
Initializes the Activity and its essential state. |
| onStart() |
Called when the Activity becomes visible. |
| onResume() |
Called when the Activity enters the foreground and can interact with the user. |
| onPause() |
Called when the Activity loses its resumed state. |
| onStop() |
Called when the Activity is no longer visible. |
| onRestart() |
Called before a stopped Activity starts again. |
| onDestroy() |
Called before the Activity is destroyed, when applicable. |
Lifecycle Example
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
}
override fun onResume() {
super.onResume()
}
override fun onPause() {
super.onPause()
}
override fun onStop() {
super.onStop()
}
}
This example uses AndroidX AppCompat. The corresponding dependency must be present in the project. In a real application, add only the lifecycle callbacks needed for the relevant work.
Interview Question 13: What Happens When an Activity Is Rotated?
Answer: By default, a configuration change such as rotation can cause the Activity to be recreated. UI state should be restored appropriately using saved instance state, a ViewModel, or persistent storage, depending on the type and lifetime of the data. A ViewModel survives configuration changes but is not by itself a guarantee that data survives process death.
17. Intents and Android Navigation
An Intent is a messaging object used to request an action from another Android component. Intents are commonly used to launch Activities and start supported services or broadcast operations.
17.1 Explicit Intent
An explicit Intent identifies the component to launch.
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("USER_NAME", "Riya")
startActivity(intent)
17.2 Reading Intent Data
val userName = intent.getStringExtra("USER_NAME")
17.3 Implicit Intent
An implicit Intent describes an action that another suitable component may handle, such as opening a web page.
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://www.justacademy.co/")
)
startActivity(intent)
In production code, handle cases where no application can resolve an implicit Intent. For sensitive data, use the appropriate secure data-transfer mechanisms and avoid passing unnecessary information.
Interview Question 14: What Is the Difference Between Explicit and Implicit Intents?
Answer: An explicit Intent identifies a particular component. An implicit Intent specifies an action and optional data, allowing Android to find a compatible component to handle the request.
18. Android Layouts and UI Components
Android user interfaces can be created using XML layouts with the View system or with Jetpack Compose. Both approaches are relevant to Android development, depending on the project.
Common View System Components
- TextView: Displays text.
- EditText: Accepts text input.
- Button: Triggers an action.
- ImageView: Displays images.
- RecyclerView: Displays efficiently managed lists.
- ConstraintLayout: Positions views using constraints.
- LinearLayout: Arranges views horizontally or vertically.
Example XML Layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Welcome to Android" />
<Button
android:id="@+id/continueButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Continue" />
</LinearLayout>
Interview Question 15: What Is the Difference Between LinearLayout and ConstraintLayout?
Answer: LinearLayout arranges children in a single horizontal or vertical direction. ConstraintLayout positions views using relationships between views and the parent, which can help build complex interfaces with a flatter view hierarchy.
19. RecyclerView and List Rendering
RecyclerView displays large or changing datasets efficiently by reusing item views instead of creating a new view for every item.
Main RecyclerView Components
- RecyclerView: The container displaying the list.
- Adapter: Supplies data and binds it to item views.
- ViewHolder: Holds references to item views.
- LayoutManager: Controls how items are arranged.
- DiffUtil: Calculates changes between lists for efficient updates.
Interview Question 16: Why Is RecyclerView Preferred for Many Lists?
Answer: RecyclerView supports view recycling, flexible layout managers, different item types, and efficient update strategies. It is well suited to lists that may contain many items or change frequently.
20. Fragments and ViewModel
20.1 What Is a Fragment?
A Fragment represents a reusable portion of an Android UI and has its own lifecycle. It is commonly hosted inside an Activity and is useful for modular screens and navigation destinations.
20.2 What Is a ViewModel?
A ViewModel stores and manages UI-related data in a lifecycle-conscious way. It can survive Activity recreation caused by configuration changes, reducing unnecessary reloading of UI state.
20.3 ViewModel Example
import androidx.lifecycle.ViewModel
class CounterViewModel : ViewModel() {
var count: Int = 0
private set
fun increment() {
count++
}
}
This basic example demonstrates state ownership. For observable UI updates, expose state using appropriate observable types such as StateFlow or LiveData and collect or observe them according to the UI framework.
Interview Question 17: What Is the Difference Between an Activity and a Fragment?
Answer: An Activity is an application component that provides an entry point for user interaction. A Fragment represents a reusable section of UI that is hosted by an Activity or another supported Fragment container. They have related but distinct lifecycles.
21. Android Data Storage
Android applications can store data locally or remotely depending on the application's requirements.
| Storage Method |
Best Use |
| DataStore |
Small application preferences and settings. |
| Room |
Structured local data backed by SQLite. |
| Files |
Documents, exported reports, and other file-based data. |
| Cloud Firestore |
Cloud-hosted documents and real-time synchronized data. |
| SharedPreferences |
Legacy key-value preferences in existing applications; DataStore is often preferred for new work. |
Interview Question 18: What Is Room?
Answer: Room is a persistence library built on SQLite. It provides entities, data access objects (DAOs), and database abstractions that help developers work with structured local data while benefiting from compile-time query checks.
22. Networking and REST API Fundamentals
Many Android applications communicate with remote services using HTTP requests and REST APIs. Kotlin developers commonly use libraries such as Retrofit and OkHttp for networking.
Important Concepts
- GET: Retrieves a resource.
- POST: Submits data or requests creation of a resource.
- PUT: Replaces a resource representation or performs an API-defined update.
- PATCH: Partially updates a resource.
- DELETE: Requests deletion of a resource.
- JSON: A common format for exchanging structured data.
- HTTP status codes: Communicate the result of a request.
Network operations should not block the main thread. Use coroutines and a suitable networking library, handle errors and timeouts, and avoid storing secrets in the app binary.
Interview Question 19: What Is Retrofit?
Answer: Retrofit is a type-safe HTTP client for Android and JVM applications. It allows developers to describe API endpoints using interfaces and integrate network requests with supported converters and asynchronous execution mechanisms.
23. Android Permissions and Security
Android permissions control access to protected resources such as location, camera, microphone, and notifications. Some permissions require runtime approval, depending on Android version and permission type.
- Declare required permissions in the manifest.
- Request runtime permissions when needed.
- Explain the purpose of sensitive permissions to users.
- Handle permission denial gracefully.
- Use HTTPS for network communications.
- Keep API keys and backend credentials appropriately protected.
- Validate authorization on the server or backend rather than trusting client-side checks.
Interview Question 20: What Is the Difference Between Normal and Dangerous Permissions?
Answer: Normal permissions generally cover lower-risk operations and are granted automatically when applicable. Dangerous permissions protect sensitive data or actions and typically require runtime approval on modern Android versions.
24. Coding Interview Questions and Solutions
Question 21: Reverse a String
Problem: Write a Kotlin function that reverses a given string.
fun reverseString(text: String): String {
return text.reversed()
}
fun main() {
println(reverseString("Android"))
}
Output: diordnA
Explanation: Kotlin provides the reversed() function for reversing a character sequence. For basic string input, this is a concise solution. More advanced Unicode text handling may require grapheme-aware processing.
Question 22: Check Whether a Number Is Even or Odd
fun checkEvenOdd(number: Int): String {
return if (number % 2 == 0) {
"Even"
} else {
"Odd"
}
}
fun main() {
println(checkEvenOdd(12))
println(checkEvenOdd(7))
}
Output: Even, Odd
Explanation: The remainder operator checks whether the number is divisible by two.
Question 23: Find the Largest of Three Numbers
fun largestOfThree(a: Int, b: Int, c: Int): Int {
return maxOf(a, b, c)
}
fun main() {
println(largestOfThree(10, 25, 15))
}
Output: 25
Explanation: Kotlin's maxOf() function returns the largest of the supplied values.
Question 24: Check Whether a String Is a Palindrome
fun isPalindrome(text: String): Boolean {
val cleaned = text.lowercase()
.filter { it.isLetterOrDigit() }
return cleaned == cleaned.reversed()
}
fun main() {
println(isPalindrome("Madam"))
println(isPalindrome("Android"))
}
Output: true, false
Explanation: The function normalizes letter case and removes non-alphanumeric characters before comparing the string with its reverse.
Question 25: Find the Factorial of a Number
fun factorial(number: Int): Long {
require(number >= 0) {
"Number must not be negative"
}
require(number <= 20) {
"Number is too large for Long factorial"
}
var result = 1L
for (i in 2..number) {
result *= i.toLong()
}
return result
}
fun main() {
println(factorial(5))
}
Output: 120
Explanation: Factorial multiplies all positive integers from 1 to the given number. By definition, the factorial of zero is 1. The example limits the input to avoid overflowing a signed Long result.
Question 26: Count Vowels in a String
fun countVowels(text: String): Int {
return text.count {
it.lowercaseChar() in "aeiou"
}
}
fun main() {
println(countVowels("Android Development"))
}
Output: 7
Explanation: The function checks each character against the five basic English vowels and counts the matches.
Question 27: Remove Duplicate Elements from a List
fun removeDuplicates(numbers: List<Int>): List<Int> {
return numbers.distinct()
}
fun main() {
println(removeDuplicates(listOf(1, 2, 2, 3, 4, 4)))
}
Output: [1, 2, 3, 4]
Explanation: The distinct() function removes duplicate values while preserving the encounter order of the first occurrence.
Question 28: Find the Sum of List Elements
fun calculateSum(numbers: List<Int>): Int {
return numbers.sum()
}
fun main() {
println(calculateSum(listOf(10, 20, 30)))
}
Output: 60
Explanation: The sum() function adds all integer values in the list. In real applications, consider numeric overflow if values or collection sizes may be large.
25. Scenario-Based Android Interview Questions
Question 29: How Would You Prevent the UI from Freezing During a Network Request?
Answer: Perform network operations asynchronously using an appropriate networking library and coroutine context. Keep UI updates on the main thread, expose loading and error states, and cancel work when its owning lifecycle ends where appropriate.
Question 30: How Would You Preserve Data During Screen Rotation?
Answer: Use a ViewModel for UI state that should survive configuration changes, saved instance state for small state that needs restoration, and persistent storage for data that must survive process death or application restarts.
Question 31: How Would You Debug an Application Crash?
Answer: Reproduce the issue, inspect Logcat and the stack trace, identify the failing line, check lifecycle and nullability issues, and isolate the cause with a small test. Add regression tests after fixing the issue.
Question 32: How Would You Load Thousands of Items Efficiently?
Answer: Use RecyclerView or an appropriate lazy list in Jetpack Compose, load data in pages, use stable identifiers where suitable, and update only changed items. Avoid loading an unnecessarily large dataset into memory at once.
Question 33: How Would You Manage API Errors?
Answer: Distinguish connectivity problems, timeouts, HTTP error responses, and data-parsing failures. Show appropriate UI states, log diagnostic information safely, and retry only when the operation and error conditions make retrying appropriate.
26. Practical Interview Preparation Exercises
Complete the following exercises to improve programming logic and Android development skills.
- Write a Kotlin program that swaps two numbers.
- Find the largest and smallest values in an integer list.
- Count the frequency of each character in a string.
- Sort a list of numbers in ascending and descending order.
- Create a Student class with properties and member functions.
- Demonstrate inheritance using a base class and a derived class.
- Write a function that handles a nullable string safely.
- Build a simple counter screen in Android.
- Navigate between two Activities using an explicit Intent.
- Display a list of items using RecyclerView.
- Create a ViewModel that stores a counter value.
- Retrieve sample JSON data from a REST API and display it.
- Store a simple record using Room.
- Implement a login screen with input validation.
- Explain the Activity lifecycle using a practical example.
27. Common Mistakes to Avoid in Interviews
- Confusing
val with a deeply immutable object.
- Using
!! without considering null-related failures.
- Forgetting to explain the time and space complexity of an algorithm.
- Performing blocking network operations on the main thread.
- Confusing Activity lifecycle callbacks with Fragment lifecycle callbacks.
- Assuming a ViewModel alone persists data across process death.
- Ignoring error handling and invalid user input.
- Using unsafe or overly broad Android permissions.
- Providing a solution without explaining why it works.
- Ignoring edge cases such as empty input, negative values, and integer overflow.
28. Best Practices for Technical Interview Preparation
- Practice writing Kotlin code without relying entirely on autocomplete.
- Understand the purpose of each language feature before memorizing syntax.
- Explain the approach before writing the solution.
- Test code with normal, boundary, and invalid inputs.
- Learn common data structures and algorithm complexity.
- Build small Android projects that demonstrate lifecycle management and UI development.
- Understand asynchronous work, coroutines, and state management.
- Review Logcat, debugging, and testing techniques.
- Use clear variable names and write small, reusable functions.
- Practice explaining trade-offs rather than claiming there is only one correct implementation.
29. Quick Revision Checklist
- Kotlin variables, data types, operators, and control flow.
- Functions, lambdas, collections, and higher-order functions.
- Null safety and exception handling.
- Classes, objects, inheritance, interfaces, and data classes.
- Coroutines and asynchronous programming.
- Android components and Activity lifecycle.
- Intents, layouts, Fragments, and RecyclerView.
- ViewModel and UI state management.
- Room, DataStore, and API integration.
- Android permissions and security basics.
- Common coding problems and edge-case testing.
- Debugging, testing, and explaining technical decisions.
30. Conclusion
Practicing Kotlin Programming and Android Fundamentals interview questions helps learners build a strong foundation for Android developer interviews. Kotlin concepts such as null safety, functions, collections, object-oriented programming, and coroutines are essential for writing reliable application code.
Android fundamentals—including the Activity lifecycle, Intents, UI layouts, RecyclerView, ViewModel, local storage, networking, and permissions—help developers understand how applications behave in real-world situations.
Consistent coding practice, practical project experience, and the ability to explain technical decisions clearly are key to interview success. Review these questions regularly, implement the examples in Android Studio, and test your solutions with different inputs.
Explore the JustAcademy Android App Development Course to continue learning, use the course demo registration page to enquire about a demo, and visit the JustAcademy website for additional information.
End of Notes: Practicing Kotlin Programming and Android Fundamentals Interview Questions